﻿using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel.Composition;
using System.Linq;
using System.Windows;
using MediaAssistant.Controls.Dialog;
using MediaAssistant.Controls.PlaylistSelector;
using MediaAssistant.Controls.TagEditor;
using MediaAssistant.Controls.WaitScreen;
using MediaAssistant.Data;
using MediaAssistant.EventArguments;
using MefBasic;
using MefBasic.Commans;
using MefBasic.Threading;
using Microsoft.Practices.Composite.Events;
using MediaAssistant.DAL;
using MediaAssistant.DAL.Constants;
using MediaAssistant.DAL.Helper;

namespace MediaAssistant.Controls.MusicList
{
    [Export(typeof(MusicListPresenter))]
    public class MusicListPresenter:APresenter<IMusicListView>
    {
        [ImportingConstructor]
        public MusicListPresenter(IMusicListView view, IEventAggregator eventAggregator) : base(view)
        {
            PlayCommand = new DelegateCommand(ExecutePlay);
            eventAggregator.GetEvent<BaseEvent<PerformSelectedItemActionEventArgs>>().Subscribe(HandlePerformSelectedItemActionEvent);
            eventAggregator.GetEvent<BaseEvent<PlayingMusicEventArgs>>().Subscribe(HandlePlayingMusicChanged);
            SelectedMusicChangedCommand = new DelegateCommand(ExecuteSelectedMusicChanged);
            AddToPlaylistCommand = new DelegateCommand(ExecuteAddToPlaylist);
            ShowInWindowsExplorerCommand = new DelegateCommand(ExecuteShowInWindowsExplorer);
            EditTagCommand = new DelegateCommand(ExecuteEditTag);
            CopyFileCommand = new DelegateCommand(ExecuteCopyFile);
            RemoveFromLibraryCommand = new DelegateCommand(ExecuteRemoveFromLibrary);
        }

        public DelegateCommand RemoveFromLibraryCommand { get; set; }

        private void ExecuteRemoveFromLibrary(object obj)
        {
            if(System.Windows.MessageBox.Show("Are you sure to remove selected music from library?", "Confirm Remove", MessageBoxButton.YesNo)==MessageBoxResult.Yes)
            {
                var waitScreenPresenter = Resolve<WaitScreenPresenter>();
                waitScreenPresenter.Show();
                var job = new Job(j => j.Store.GetObject<LibraryDataSource>().Remove(j.Store.GetObjects<Music>()));
                job.Store.AddRange<Music>(View.GetSelectedMusics());
                job.Store.Add(DataSource);
                job.StartBlocked();
                waitScreenPresenter.Hide();
            }
        }

        public DelegateCommand CopyFileCommand { get; set; }

        private void ExecuteCopyFile(object obj)
        {
            var filesToCopy = new StringCollection();
            filesToCopy.AddRange(View.GetSelectedMusics().Select(m => m.FullPath).ToArray());
            Clipboard.SetFileDropList(filesToCopy);
        }

        public DelegateCommand EditTagCommand { get; set; }

        private void ExecuteEditTag(object obj)
        {
            Resolve<TagEditorPresenter>().ShowDialog(View.GetSelectedMusics());
        }

        private void HandlePlayingMusicChanged(PlayingMusicEventArgs obj)
        {
            View.ScrollIntoView(obj.Music);
        }

        public DelegateCommand ShowInWindowsExplorerCommand { get; set; }

        private void ExecuteShowInWindowsExplorer(object obj)
        {
            SystemHelper.LocateInWndowsExplorer(DataSource.SelectedMusic.FullPath);
        }

        public DelegateCommand AddToPlaylistCommand { get; set; }

        private void ExecuteAddToPlaylist(object obj)
        {
            var playlistSelectorPresenter = Resolve<PlaylistSelectorPresenter>();
            if (Resolve<IDialogPresenter>().ShowDialog("Create or select playlist", playlistSelectorPresenter) == DialogResult.Ok)
            {
                DatabaseManager.Instance.AddToPlaylist(View.GetSelectedMusics(), playlistSelectorPresenter.Playlist);
            }
        }

        public DelegateCommand SelectedMusicChangedCommand { get; set; }

        private void ExecuteSelectedMusicChanged(object obj)
        {
            DataSource.SelectedMusic = (Music)obj;
        }

        private void HandlePerformSelectedItemActionEvent(PerformSelectedItemActionEventArgs obj)
        {
            ProbabilityVisibility = obj.Data.Id==LibraryItemType.NowPlayingPlaylist ? Visibility.Visible : Visibility.Collapsed;
        }


        public Visibility ProbabilityVisibility
        {
            get { return (Visibility)GetValue(ProbabilityVisibilityProperty); }
            set { SetValue(ProbabilityVisibilityProperty, value); }
        }

        public static readonly DependencyProperty ProbabilityVisibilityProperty =
            DependencyProperty.Register("ProbabilityVisibility", typeof(Visibility), typeof(MusicListPresenter), new UIPropertyMetadata(Visibility.Collapsed));


        public DelegateCommand PlayCommand { get; set; }

        private void ExecutePlay(object obj)
        {
            var musics = View.GetSelectedMusics();
            if(!musics.Any())
                return;
            DataSource.Play(DataSource.SelectedMusic);
            var waitScreenPresenter = Resolve<WaitScreenPresenter>();
            waitScreenPresenter.Show();
            var playingMusic = DataSource.PlayingMusic;
            var job = new Job(j =>
                                  {
                                      var datasource = j.Store.GetObject<LibraryDataSource>();
                                      var selectedMusics = j.Store.GetObject<IEnumerable<Music>>();
                                      var selectedMusic = j.Store.GetObject<Music>();
                                      DatabaseManager.Instance.SetNowPlayingPlaylist(datasource.ResultMusics, selectedMusics, playingMusic);
                                      datasource.StartMusicDJ(selectedMusic);
                                  });
            job.Store.Add(DataSource);
            job.Store.Add(musics);
            job.Store.Add(DataSource.SelectedMusic);
            job.JobCompleted += (s, e) => waitScreenPresenter.Hide();
            job.Start();
        }


        [Import]
        public LibraryDataSource DataSource
        {
            get { return (LibraryDataSource)GetValue(DataSourceProperty); }
            set { SetValue(DataSourceProperty, value); }
        }

        public static readonly DependencyProperty DataSourceProperty =
            DependencyProperty.Register("DataSource", typeof(LibraryDataSource), typeof(MusicListPresenter), new UIPropertyMetadata(null));

        public void OnItemDoubleClicked(Music music)
        {
            PlayCommand.Execute(music);
        }
    }
}
